import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { OperationLog } from './entities/operation-log.entity';
import { Readable } from 'stream';
import { Response } from 'express';

@Injectable()
export class OperationLogService {
  constructor(
    @InjectRepository(OperationLog)
    private operationLogRepository: Repository<OperationLog>,
  ) {}

  async findWithFilters(filters: {
    userId?: number;
    username?: string;
    operationType?: string;
    startDate?: Date;
    endDate?: Date;
    method?: string;
    status?: number;
    page?: number;
    limit?: number;
  }) {
    const query = this.operationLogRepository.createQueryBuilder('log')
      .select([
        'log.id',
        'log.userId',
        'log.username',
        'log.method',
        'log.path',
        'log.operationType',
        'log.ip',
        'log.userAgent',
        'log.status',
        'log.duration',
        'log.createdAt'
      ]);

    if (filters.userId) {
      query.andWhere('log.userId = :userId', { userId: filters.userId });
    }
    if (filters.username) {
      query.andWhere('log.username LIKE :username', { username: `%${filters.username}%` });
    }
    if (filters.operationType) {
      query.andWhere('log.operationType = :operationType', { operationType: filters.operationType });
    }
    if (filters.startDate) {
      query.andWhere('log.createdAt >= :startDate', { startDate: filters.startDate });
    }
    if (filters.endDate) {
      query.andWhere('log.createdAt <= :endDate', { endDate: filters.endDate });
    }
    if (filters.method) {
      query.andWhere('log.method = :method', { method: filters.method });
    }
    if (filters.status) {
      query.andWhere('log.status = :status', { status: filters.status });
    }

    const page = filters.page || 1;
    const limit = filters.limit || 10;
    const skip = (page - 1) * limit;

    query.orderBy('log.createdAt', 'DESC')
      .skip(skip)
      .take(limit);

    const [items, total] = await query.getManyAndCount();

    return {
      items,
      total,
      page,
      limit,
      totalPages: Math.ceil(total / limit),
    };
  }

  async getStatistics(startDate: Date, endDate: Date) {
    const query = this.operationLogRepository.createQueryBuilder('log');

    // 按操作类型统计
    const operationTypeStats = await query
      .select('operationType')
      .addSelect('COUNT(*)', 'count')
      .where('createdAt BETWEEN :startDate AND :endDate', { startDate, endDate })
      .groupBy('operationType')
      .getRawMany();

    // 按用户统计
    const userStats = await query
      .select('userId')
      .addSelect('username')
      .addSelect('COUNT(*)', 'count')
      .where('createdAt BETWEEN :startDate AND :endDate', { startDate, endDate })
      .groupBy('userId')
      .addGroupBy('username')
      .getRawMany();

    // 按状态码统计
    const statusStats = await query
      .select('status')
      .addSelect('COUNT(*)', 'count')
      .where('createdAt BETWEEN :startDate AND :endDate', { startDate, endDate })
      .groupBy('status')
      .getRawMany();

    return {
      operationTypeStats,
      userStats,
      statusStats,
    };
  }

  async exportLogs(filters: any): Promise<Readable> {
    const query = this.operationLogRepository.createQueryBuilder('log')
      .select([
        'log.createdAt',
        'log.username',
        'log.operationType',
        'log.method',
        'log.path',
        'log.status',
        'log.duration',
        'log.ip'
      ])
      .orderBy('log.createdAt', 'DESC')
      .limit(1000);

    // 添加筛选条件
    if (filters.userId) {
      query.andWhere('log.userId = :userId', { userId: filters.userId });
    }
    if (filters.username) {
      query.andWhere('log.username LIKE :username', { username: `%${filters.username}%` });
    }
    if (filters.operationType) {
      query.andWhere('log.operationType = :operationType', { operationType: filters.operationType });
    }
    if (filters.startDate) {
      query.andWhere('log.createdAt >= :startDate', { startDate: filters.startDate });
    }
    if (filters.endDate) {
      query.andWhere('log.createdAt <= :endDate', { endDate: filters.endDate });
    }
    if (filters.method) {
      query.andWhere('log.method = :method', { method: filters.method });
    }
    if (filters.status) {
      query.andWhere('log.status = :status', { status: filters.status });
    }

    const stream = new Readable({
      read() {}
    });

    // 使用流式查询
    const queryStream = await query.stream();
    
    queryStream.on('data', (chunk: any) => {
      const log = chunk as OperationLog;
      const formattedLog = {
        createdAt: new Date(log.createdAt).toISOString(),
        username: log.username || '-',
        operationType: log.operationType,
        method: log.method,
        path: log.path,
        status: log.status,
        duration: log.duration,
        ip: log.ip || '-'
      };
      stream.push(JSON.stringify(formattedLog) + '\n');
    });

    queryStream.on('end', () => {
      stream.push(null);
    });

    queryStream.on('error', (error) => {
      console.error('Stream error:', error);
      stream.push(null);
    });

    return stream;
  }
}









